/*
 * © 2024 huayunliufeng保留所有权利, 依据MIT许可证发布。
 * 请勿更改或删除版权声明或此文件头。
 * 此代码是免费软件, 您可以重新分发和/或修改它。
 * 开源是希望它有用, 但不对代码做任何保证。
 * 如有疑问请联系: huayunliufeng@163.com
 */

package io.github.huayunliufeng.common.constant;

/**
 * 内存容量的单位枚举。如果使用long或double来表示bit, 最大是1EB, 大约1048576TB。
 *
 * @author zhongq 2024/5/30 16:15
 * @version 0.0.7
 * @since 0.0.7
 */
public enum MemoryUnitEnum {
    /**
     * 比特(Bit, b)
     */
    BIT,

    /**
     * 字节(Byte, B), 1B = 8bit
     */
    B,

    /**
     * 千字节(Kilobyte, KB), 1kb = 1024b
     */
    KB,

    /**
     * 兆字节(Megabyte, MB), 1mb = 1024kb
     */
    MB,

    /**
     * 吉字节(Gigabyte, GB), 1gb = 1024mb
     */
    GB,

    /**
     * 太字节(Terabyte, TB), 1tb = 1024gb
     */
    TB,

    /**
     * 拍字节(Petabyte, PB), 1pb = 1024tb
     */
    PB,

    /**
     * 艾字节(Exabyte, EB), 1eb = 1024pb
     */
    EB,

    /**
     * 泽字节(Zettabyte, ZB), 1zb = 1024eb
     */
    ZB,

    /**
     * 尧字节(Yottabyte, YB), 1yb = 1024zb
     */
    YB;

    /**
     * 将当前内存容量转换为指定单位
     *
     * @param memory memory
     * @param src    当前单位
     * @param dst    目标单位
     * @return double
     */
    public static double memoryConvert(double memory, MemoryUnitEnum src, MemoryUnitEnum dst) {
        long l = memoryToBit(memory, src);
        return bitMemoryTo(l, dst);
    }

    /**
     * 将内存容量转换为bit
     *
     * @param memory memory
     * @param src    当前单位
     * @return long
     */
    public static long memoryToBit(double memory, MemoryUnitEnum src) {
        switch (src) {
            case BIT:
                return (long) memory;
            case B:
                return (long) (memory * 8);
            case KB:
                return (long) (memory * 8 * 1024);
            case MB:
                return (long) (memory * 8 * 1024 * 1024);
            case GB:
                return (long) (memory * 8 * 1024 * 1024 * 1024);
            case TB:
                return (long) (memory * 8 * 1024 * 1024 * 1024 * 1024);
            case PB:
                return (long) (memory * 8 * 1024 * 1024 * 1024 * 1024 * 1024);
            case EB:
                return (long) (memory * 8 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
            case ZB:
                return (long) (memory * 8 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
            case YB:
                return (long) (memory * 8 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
            default:
                throw new RuntimeException("未知的内存单位。");
        }
    }

    /**
     * 将bit单位的内存容量转换为指定单位的内存容量
     *
     * @param memory memory
     * @param dst    目标单位
     * @return double
     */
    public static double bitMemoryTo(long memory, MemoryUnitEnum dst) {
        switch (dst) {
            case BIT:
                return memory;
            case B:
                return memory / 8.0;
            case KB:
                return memory / (8.0 * 1024);
            case MB:
                return memory / (8.0 * 1024 * 1024);
            case GB:
                return memory / (8.0 * 1024 * 1024 * 1024);
            case TB:
                return memory / (8.0 * 1024 * 1024 * 1024 * 1024);
            case PB:
                return memory / (8.0 * 1024 * 1024 * 1024 * 1024 * 1024);
            case EB:
                return memory / (8.0 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
            case ZB:
                return memory / (8.0 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
            case YB:
                return memory / (8.0 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024 * 1024);
            default:
                throw new RuntimeException("未知的内存单位。");
        }
    }
}
